package com.ruoyi.develop.finance.financeAp.service.impl;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.ruoyi.common.utils.DictUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.uuid.IdUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.ruoyi.constants.BusinessConstants;
import com.ruoyi.develop.finance.financeBuyInvoice.domain.FinanceBuyInvoice;
import com.ruoyi.develop.lvDaohuo.domain.LvDaohuo;
import com.ruoyi.develop.lvRuku.domain.LvRuku;
import com.ruoyi.develop.payRecord.domain.PayRecord;
import com.ruoyi.export.service.impl.ExportServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.develop.finance.financeAp.mapper.FinanceApMapper;
import com.ruoyi.develop.finance.financeAp.domain.FinanceAp;
import com.ruoyi.develop.finance.financeAp.service.IFinanceApService;

/**
 * 应付账单Service业务层处理
 *
 * @author lmm
 * @date 2025-07-27
 */
@Service
public class FinanceApServiceImpl implements IFinanceApService {
    @Resource
    private FinanceApMapper financeApMapper;
    @Autowired
    private ExportServiceImpl exportService;

    /**
     * 查询应付账单
     *
     * @param id 应付账单主键
     * @return 应付账单
     */
    @Override
    public FinanceAp selectById(String id) {
        return financeApMapper.selectById(id);
    }

    /**
     * 查询应付账单列表
     *
     * @param entity 应付账单
     * @return 应付账单
     */
    @Override
    public List<FinanceAp> selectList(FinanceAp entity) {
        return financeApMapper.selectList(entity);
    }

    @Override
    public void exportData(HttpServletRequest request, HttpServletResponse response, FinanceAp entity) {
        List<FinanceAp> list = financeApMapper.selectList(entity);
        for (FinanceAp financeAp : list) {
            Map<String, Object> params = new HashMap<>();
            params.put("occurDate", DateUtils.formatDate(financeAp.getOccurDate(), "yyyy-MM-dd"));
            params.put("invoiceDate", DateUtils.formatDate(financeAp.getInvoiceDate(), "yyyy-MM-dd"));
            params.put("payRecordDate", DateUtils.formatDate(financeAp.getPayRecordDate(), "yyyy-MM-dd"));
            params.put("type", DictUtils.getDictLabel("ap_type", financeAp.getType()));
            financeAp.setParams(params);
        }
        String fileName = "供应商应付列表.xlsx";
        String templateName = "供应商应付列表导出模板.xlsx";
        Map<String, Object> params = new HashMap<>();
        params.put("list", list);
        exportService.baseXlsxExport(fileName, params, templateName, request, response);
    }



    /**
     * 新增应付账单
     *
     * @param entity 应付账单
     * @return 结果
     */
    @Override
    public int insert(FinanceAp entity) {
        if (StringUtils.isBlank(entity.getId())) {
            entity.setId(IdUtils.fastSimpleUUID());
        }
        if(StringUtils.isBlank(entity.getNos())){
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
            String today = sdf.format(entity.getOccurDate()==null?new Date():entity.getOccurDate());
            String codeMaxString = financeApMapper.selectMaxCode(today);
            if(StringUtils.isNotBlank(codeMaxString)){
                // 最大编号+1
                codeMaxString = Long.parseLong(codeMaxString)+1+"";
            }else{
                codeMaxString = today+"0001";
            }
            entity.setNos(codeMaxString);
        }
        entity.setCreateBy(SecurityUtils.getUsername());
        entity.setCreateTime(DateUtils.getNowDate());
        return financeApMapper.insert(entity);
    }

    /**
     * 修改应付账单
     *
     * @param entity 应付账单
     * @return 结果
     */
    @Override
    public int update(FinanceAp entity) {
        entity.setUpdateBy(SecurityUtils.getUsername());
        entity.setUpdateTime(DateUtils.getNowDate());
        return financeApMapper.update(entity);
    }

    /**
     * 批量删除应付账单
     *
     * @param ids 需要删除的应付账单主键
     * @return 结果
     */
    @Override
    public int deleteByIds(String[] ids) {
        return financeApMapper.deleteByIds(ids);
    }

    /**
     * 删除应付账单信息
     *
     * @param id 应付账单主键
     * @return 结果
     */
    @Override
    public int deleteById(String id) {
        return financeApMapper.deleteById(id);
    }


    /**
     * 根据发票新增应付
     *
     * @param buyInvoice 发票
     */
    @Override
    public void addByInvoice(FinanceBuyInvoice buyInvoice) {
        // 应付 先查询该供应商有没有在应付列表里 如果有则查询最后一条数据，获取应付余额
        // 如果没有则新增一条数据
        FinanceAp financeApLastOne = financeApMapper.selectLastOneBySupplierId(buyInvoice.getSupplierId());
        BigDecimal remainMoney = BigDecimal.ZERO;
        if (financeApLastOne != null) {
            remainMoney = financeApLastOne.getRemainMoney();
        }
        FinanceAp financeAp = new FinanceAp();
        financeAp.setInvoiceCode(buyInvoice.getInvoiceCode());
        financeAp.setInvoiceId(buyInvoice.getId());
        financeAp.setInvoiceNos(buyInvoice.getNos());
        financeAp.setInvoiceDate(buyInvoice.getInvoiceDate());
        financeAp.setPayMoney(buyInvoice.getTotalAmount());
        financeAp.setRemainMoney(remainMoney.add(buyInvoice.getTotalAmount()));
        financeAp.setType(BusinessConstants.AP_TYPE_INVOICE);
        financeAp.setSupplierId(buyInvoice.getSupplierId());
        financeAp.setSupplierName(buyInvoice.getSupplierName());
        financeAp.setOccurDate(DateUtils.getNowDate());
        this.insert(financeAp);
    }

    /**
     * 根据付款新增应付
     *
     * @param payRecord 付款
     */
    @Override
    public void addByPayRecord(PayRecord payRecord) {
        // 应付 先查询该供应商有没有在应付列表里 如果有则查询最后一条数据，获取应付余额
        // 如果没有则新增一条数据
        FinanceAp financeApLastOne = financeApMapper.selectLastOneBySupplierId(payRecord.getSupplierId());
        BigDecimal remainMoney = BigDecimal.ZERO;
        if (financeApLastOne != null) {
            remainMoney = financeApLastOne.getRemainMoney();
        }
        FinanceAp financeAp = new FinanceAp();
        financeAp.setPayRecordNo(payRecord.getNos());
        financeAp.setPaidMoney(payRecord.getMoney());
        financeAp.setType(BusinessConstants.AP_TYPE_PAY_SURE);
        financeAp.setPayRecordId(payRecord.getId());
        financeAp.setPayRecordDate(payRecord.getPayTime());
        financeAp.setRemainMoney(remainMoney.subtract(payRecord.getMoney()));
        financeAp.setSupplierId(payRecord.getSupplierId());
        financeAp.setSupplierName(payRecord.getSupplierName());
        financeAp.setOccurDate(DateUtils.getNowDate());
        this.insert(financeAp);
    }


    /**
     * 根据取消付款
     *
     * @param payRecord 付款
     */
    @Override
    public void addByPayRecordCancel(PayRecord payRecord) {
        // 应付 先查询该供应商有没有在应付列表里 如果有则查询最后一条数据，获取应付余额
        // 如果没有则新增一条数据
        FinanceAp financeApLastOne = financeApMapper.selectLastOneBySupplierId(payRecord.getSupplierId());
        BigDecimal remainMoney = BigDecimal.ZERO;
        if (financeApLastOne != null) {
            remainMoney = financeApLastOne.getRemainMoney();
        }
        FinanceAp financeAp = new FinanceAp();
        financeAp.setPayRecordNo(payRecord.getNos());
        financeAp.setPaidMoney(payRecord.getMoney().negate());
        financeAp.setType(BusinessConstants.AP_TYPE_PAY_CANCEL);
        financeAp.setPayRecordId(payRecord.getId());
        financeAp.setPayRecordDate(payRecord.getPayTime());
        financeAp.setRemainMoney(remainMoney.add(payRecord.getMoney()));
        financeAp.setSupplierId(payRecord.getSupplierId());
        financeAp.setSupplierName(payRecord.getSupplierName());
        financeAp.setOccurDate(DateUtils.getNowDate());
        this.insert(financeAp);
    }


    /**
     * 根据入库新增应付
     * @param lvRuku 入库
     */
    @Override
    public void addByStoreIn(LvRuku lvRuku) {
        // 应付 先查询该供应商有没有在应付列表里 如果有则查询最后一条数据，获取应付余额
        // 如果没有则新增一条数据
        FinanceAp financeApLastOne = financeApMapper.selectLastOneBySupplierId(lvRuku.getSupplierId());
        BigDecimal remainMoney = BigDecimal.ZERO;
        if (financeApLastOne != null) {
            remainMoney = financeApLastOne.getRemainMoney();
        }
        FinanceAp financeAp = new FinanceAp();
        financeAp.setPayMoney(lvRuku.getMoney());
        financeAp.setType(BusinessConstants.AP_TYPE_STORE_IN);
        financeAp.setStoreInId(lvRuku.getId());
        financeAp.setStoreInNos(lvRuku.getNos());
        financeAp.setStoreInDate(lvRuku.getRukuDate());
        financeAp.setRemainMoney(remainMoney.subtract(lvRuku.getMoney()));
        financeAp.setSupplierId(lvRuku.getSupplierId());
        financeAp.setSupplierName(lvRuku.getSupplierName());
        financeAp.setOccurDate(DateUtils.getNowDate());
        this.insert(financeAp);
    }


    /**
     * 根据入库退货新增应付
     * @param lvRuku 入库
     */
    @Override
    public void addByStoreOut(LvRuku lvRuku) {
        // 应付 先查询该供应商有没有在应付列表里 如果有则查询最后一条数据，获取应付余额
        // 如果没有则新增一条数据
        FinanceAp financeApLastOne = financeApMapper.selectLastOneBySupplierId(lvRuku.getSupplierId());
        BigDecimal remainMoney = BigDecimal.ZERO;
        if (financeApLastOne != null) {
            remainMoney = financeApLastOne.getRemainMoney();
        }
        FinanceAp financeAp = new FinanceAp();
        financeAp.setPayMoney(lvRuku.getMoney().negate());
        financeAp.setType(BusinessConstants.AP_TYPE_STORE_OUT);
        financeAp.setStoreInId(lvRuku.getId());
        financeAp.setStoreInNos(lvRuku.getNos());
        financeAp.setStoreInDate(lvRuku.getRukuDate());
        financeAp.setRemainMoney(remainMoney.add(lvRuku.getMoney()));
        financeAp.setSupplierId(lvRuku.getSupplierId());
        financeAp.setSupplierName(lvRuku.getSupplierName());
        financeAp.setOccurDate(DateUtils.getNowDate());
        this.insert(financeAp);
    }





}
